package com.sencorsta.ids.game.world.pak;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sencorsta.ids.common.service.MsgService;
import com.sencorsta.ids.common.service.MysqlService;
import com.sencorsta.ids.common.service.RedisService;
import com.sencorsta.ids.core.log.Out;
import com.sencorsta.ids.game.db.RpMassage;
import com.sencorsta.ids.game.db.SettlementResult;
import com.sencorsta.ids.game.db.TradeRecord;
import com.sencorsta.ids.game.db.Wallet;
import com.sencorsta.ids.game.proto.GamePushRedPackageByProto;
import com.sencorsta.ids.game.proto.GamePushRobMoneyByProto;
import com.sencorsta.ids.game.util.MoneyPiece;
import com.sencorsta.ids.game.util.PacketMoney;
import com.sencorsta.ids.game.util.PushAndSaved;
import com.sencorsta.ids.game.world.bean.Player;
import com.sencorsta.ids.game.world.bean.World;
import com.sencorsta.ids.game.world.room.LongHuRoom;
import com.sencorsta.utils.date.DateUtil;
import com.sencorsta.utils.random.ICeRandom;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;


/**
 * @author TAO
 * @description: 龙虎玩法
 * @date 2019/11/19 22:41
 */
public class LongHuPackage extends RedPackage implements RedisService {

    public int detain;//龙虎类型 1龙  2虎

    public int longy;//龙

    public int hu;//虎

    public int victoryNumber = 0;//胜率

    public int wol;//龙虎输赢结果

    public int longyNumber;//玩家分配到龙的个数

    public LongHuRoom longHuRoom;


    public LongHuPackage(String sendUserId, String rpId, int count, long amount, LongHuRoom longHuRoom, long sendDeposit, int detain, boolean isRobotPack) {
        super(sendUserId, rpId, count, amount, computeRobDeposit(amount, longHuRoom), longHuRoom.roomId, isRobotPack);//初始化父类公共属性
        this.detain = detain;
        this.moneyPieces = PacketMoney.getPacketMoney(PacketMoney.getRandomWeightsList(amount, count), amount, count, 1);
        this.sendDeposit = sendDeposit;//为发包者初始化冻结资金
        this.longHuRoom = longHuRoom;

        analysis();
    }


    //得到抢红包的人的押金robDeposit
    public static long computeRobDeposit(long amount, LongHuRoom longHuRoom) {
        //发包金额 * 房间倍率
        return (long) (amount * longHuRoom.magnification);
    }

    //抢红包
    public void rob(Player player) {
        try {

            Out.debug("-----------龙虎抢红包--rob-----------", player.userId);
            if (count == 0 || status != 0) {//判断红包数量
                Out.debug("红包已抢完");
                return;
            }
            if (rpResult.containsKey(player.userId)) {
                Out.debug("该红包你以领取过");
                return;
            }


            Long robAmount;//抢到的红包金额
            int point;//点数


            //不加控制默认
            int index = getNextIndex();
            //机器人发包
            if (isRobotRobMustWin) {
                if (isRobotPack) {
                    //玩家优先拿输包
                    if (player.type == 1) {
                        index = getLoseIndex();
                        if (index < 0) {
                            //没有可以用的包了
                            index = getNextIndex();
                        }
                    }
                    //机器人优先拿赢包
                    if (player.type == 2) {
                        index = getWinIndex();
                        if (index < 0) {
                            index = getNextIndex();
                        }
                    }
                } else {
                    //玩家发包 机器人只拿赢包
                    if (player.type == 2) {
                        index = getWinIndex();
                        if (index < 0) {
                            //没有可以用的包了
                            return;
                        }
                    }
                }
            }

            playerMap.put(player.userId, player);
            robAmount = moneyPieces.get(index).getMoney();
            point = moneyPieces.get(index).getThunderNumber();

            moneyPieces.get(index).setRobed(true);


            //将抢的红包和用户对应起来
            JSONObject result = new JSONObject();
            result.put("robUserId", player.userId);
            result.put("amount", robAmount);
            result.put("detain", point);
            result.put("time", DateUtil.getDateTime());
            result.put("nickname", player.nickname);
            result.put("portrait", player.portrait);
            rpResult.put(player.userId, result);

            if (point <= 4 && point >= 0) {//为龙
                longyNumber = ++longyNumber;
            }

            balance = balance - robAmount;
            //longHuRoom.rpPackage.put(rpId, longHuPackage);

            //冻结抢包者的最高赔款金额 --防止在抢到红包到结算期间去抢其他红包（最终导致这里的包在结算时余额不够）
            player.onRob(rpId, -robDeposit, robDeposit);

            GamePushRobMoneyByProto.PushRobMoney.Builder push = GamePushRobMoneyByProto.PushRobMoney.newBuilder();
            push.setGameId(World.LONGHU);
            push.setRoomId(roomId);
            push.setRpId(rpId);
            push.setMoney(robAmount);
            Out.debug("龙虎即将为==》", player.userId, "__推送__");
            MsgService.pushBySID(PushAndSaved.pushProto(player.userId, "push.RobMoney", push), player.SID);
            if (!moneyRecode.containsKey(player.userId)) {//参与抢包用户添加recode的--防止报空
                JSONObject recode = new JSONObject();
                moneyRecode.put(player.userId, recode);
            }
            count = count - 1;
        } catch (Exception e) {
            e.printStackTrace();
            Out.error(this.toString());
        }
    }

    public void update() {
        this.time -= 1;//当前包的时间减1秒
        Out.debug("当前龙虎红包Id==>", rpId, "__房间为==>", roomId, "  count==>", count, "  time==>", time);
        if (status == 0) {
            if (time == 0) {//当前包的死期已到，他妈的干掉
                if (rpResult == null) {//红包结算记录为空，代表
                    Out.debug("当前包无人问津，自动撤回");
                    status = 2;
                    Settlement();//结算
                    return;
                }
                Out.debug("当前包的死期已到，开始清算结果");
                status = 1;
                Settlement();//结算
                return;
            }


            if (count == 0) {//红包抢完了
                Out.debug("当前红包已抢完", "红包Id", rpId);
                status = 1;
                Settlement();//结算
                return;
            }

        }

    }

    public void makeLongWin() {
        this.longy = ICeRandom.getDynamic().nextInt(12) + 2;//生成龙的点数
        this.hu = ICeRandom.getDynamic().nextInt(longy-1) + 1;//生成虎的点数
    }

    public void makehuWin() {
        this.hu = ICeRandom.getDynamic().nextInt(12) + 2;//生成龙的点数
        this.longy = ICeRandom.getDynamic().nextInt(hu-1) + 1;//生成虎的点数
    }

    @Override
    public void analysis() {

        this.longy = ICeRandom.getDynamic().nextInt(13) + 1;//生成龙的点数
        this.hu = ICeRandom.getDynamic().nextInt(13) + 1;//生成虎的点数

        //判断是否是机器人发包
        boolean isMustWin = World.getInstance().isMustWinbyRoom(roomId);
        if (isMustWin) {
            isRobotRobMustWin = true;
        }
        //统计 第一波 的数量
        int countLongPlayer=0;
        for (int i = 0; i < moneyPieces.size(); i++) {
            MoneyPiece jsonObject = moneyPieces.get(i);
            int jThunderNumber = jsonObject.getThunderNumber();

            boolean isLongPlayer = false;
            isLongPlayer = jThunderNumber <= 4;

            if(isLongPlayer==true){
                countLongPlayer++;
            }
        }

        //如果机器人发包 countWinpack 的个数少于一半 就改变发包者的龙虎点
        if (isRobotRobMustWin==true) {
            if (isRobotPack) {
                if ( detain==1){
                    if (count-countLongPlayer<countLongPlayer){
                        // 第一波多 多的输  庄家选的是龙  让虎赢
                        makehuWin();
                    }else if (count-countLongPlayer>countLongPlayer){
                        // 第一波少 少的赢 庄家选的是龙  让龙赢
                        makeLongWin();
                    }else{
                        //平局
                        longy=hu;
                    }
                }else if (detain==2){
                    if (count-countLongPlayer<countLongPlayer){
                        // 第一波多 多的输  庄家选的是虎  让龙赢
                        makeLongWin();
                    }else if (count-countLongPlayer>countLongPlayer){
                        // 第一波少 少的赢 庄家选的是虎  让虎赢
                        makehuWin();
                    }else{
                        //平局
                        longy=hu;
                    }
                }
            }else {//玩家发包刚好相反
                if ( detain==1){
                    if (count-countLongPlayer<countLongPlayer){
                        makeLongWin();
                    }else if (count-countLongPlayer>countLongPlayer){
                        // 第一波少 少的赢 庄家选的是龙  让龙赢
                        makehuWin();
                    }else{
                        //平局
                        longy=hu;
                    }
                }else if (detain==2){
                    if (count-countLongPlayer<countLongPlayer){
                        makehuWin();
                    }else if (count-countLongPlayer>countLongPlayer){
                        // 第一波少 少的赢 庄家选的是龙  让龙赢
                        makeLongWin();
                    }else{
                        //平局
                        longy=hu;
                    }
                }
            }
        }

        for (int i = 0; i < moneyPieces.size(); i++) {
            MoneyPiece jsonObject = moneyPieces.get(i);
            int jThunderNumber = jsonObject.getThunderNumber();

            boolean isLong = longy > hu;
            boolean isLongPlayer = false;
            if (detain == 1) {
                isLongPlayer = jThunderNumber <= 4;
            } else if (detain == 2) {
                isLongPlayer = jThunderNumber > 4;
            }

            int temp = 0;
            if (longy != hu) {
                if (isLong == true) {
                    if (isLongPlayer == true) {
                        temp = 10000;
                    } else {
                        temp = -10000;
                    }
                } else {
                    if (isLongPlayer == true) {
                        temp = -10000;
                    } else {
                        temp = 10000;
                    }
                }
            }
            moneyPieces.get(i).setScore(temp);
        }
        if (longy > hu) {//1 龙赢
            wol = 1;
        } else if (longy == hu) {//0 和
            wol = 0;
        } else {//2 虎赢
            wol = 2;
        }
        for (int j = 0; j < moneyPieces.size(); j++) {
            if (moneyPieces.get(j).getScore() > 0) {
                moneyPieces.get(j).setWin(true);
            } else {
                moneyPieces.get(j).setWin(false);
            }
        }
//        Out.warn("龙虎？"+(longy > hu)+" 龙："+longy+" hu:"+hu);
//        Out.warn("庄家？"+(detain));
//        Out.warn("电脑？"+(isRobotPack));
//        Out.warn("数据："+JSON.toJSONString(moneyPieces));
    }

    //通知结算
    public void Settlement() {
        try {
            Out.debug("---------------龙虎开始结算----------------");
            Out.debug("------------------------龙虎包----rpResult----------------------------");
            Out.debug("龙虎红包详情：", this.toString());
            Out.debug("龙虎红包记录：", rpResult);


            double magnification = longHuRoom.magnification;//得到当前房间倍率
            long transportAmount = getTransportAmount(magnification);//得到输的钱

            long bankWinMoney = 0;
            for (var userId : rpResult.keySet()) {
                JSONObject userRobInfo = (JSONObject) rpResult.get(userId);//得到的userId的结算记录
                int point = userRobInfo.getInteger("detain");//得到当前用户的点数

                Out.debug("point-->", point);

                Out.debug("当前房间倍率==》", magnification);

                int robStatus = 0;//得到抢包者的类型
                //得到抢包者分配的点数===》转变为对应的龙虎

                if (point <= 4 && point >= 0) {//为龙
                    robStatus = 1;
                } else {//为虎
                    robStatus = 2;
                }



                /**
                 * 如果发包者选对了
                 *      吃对立面的玩家的钱，陪分配到自己选的一方的玩家的钱
                 * 如果发包者选错了
                 *      吃分配到自己选的一方的玩家的钱，陪对立面的玩家的钱
                 */
                long leisureAmount = userRobInfo.getLong("amount");//得到当前用户抢到的钱
                JSONObject recode = moneyRecode.getJSONObject(userId);//得到当前玩家的账单记录
                recode.put("robMoney", leisureAmount);//将抢到的钱存到当前玩家的账单记录
                int jThunderNumber = point;

                boolean isLong = longy > hu;
                boolean isLongPlayer = false;
                if (detain == 1) {
                    isLongPlayer = jThunderNumber <= 4;
                } else if (detain == 2) {
                    isLongPlayer = jThunderNumber > 4;
                }

                int temp = 0;
                if (longy != hu) {
                    if (isLong == true) {
                        if (isLongPlayer == true) {
                            recode.put("resultMoney", transportAmount);//加钱
                            bankWinMoney -= transportAmount;
                        } else {
                            victoryNumber = ++victoryNumber;//发包者胜率++
                            recode.put("resultMoney", -transportAmount);//扣钱
                            bankWinMoney += transportAmount;
                        }
                    } else {
                        if (isLongPlayer == true) {
                            victoryNumber = ++victoryNumber;//发包者胜率++
                            recode.put("resultMoney", -transportAmount);//扣钱
                            bankWinMoney += transportAmount;
                        } else {
                            recode.put("resultMoney", transportAmount);//加钱
                            bankWinMoney -= transportAmount;
                        }
                    }
                }

//                if (wol == detain) {//发包者选中了
//                    //当前玩家和庄一样
//                    if (robStatus == detain) {//发包者赔分配到自己下面的玩家金额，--------抢包者陪钱
//                        //玩家加钱--//发包者陪钱
//                        recode.put("resultMoney", transportAmount);//加钱
//                        bankWinMoney -= transportAmount;
//                    } else {//吃对立面玩家的金额----发包者拿钱
//                        victoryNumber = ++victoryNumber;//发包者胜率++
//
//                        recode.put("resultMoney", -transportAmount);//扣钱
//                        bankWinMoney += transportAmount;
//
//                    }
//                } else {//发包者没选中
//                    if (robStatus == detain) {//吃赔分配到自己下面的玩家金额，----发包者赔钱
//                        victoryNumber = ++victoryNumber;//发包者胜率++
//                        //发包者加钱--玩家赔钱
//                        recode.put("resultMoney", transportAmount);//加钱
//                        bankWinMoney -= transportAmount;
//                    } else {//发包赔对立面玩家的金额---------抢包者拿钱
//                        //玩家加钱--发包者陪钱
//                        recode.put("resultMoney", -transportAmount);//扣钱
//                        bankWinMoney += transportAmount;
//                    }
//                }
            }
            moneyRecode.getJSONObject(sendUserId).put("sendAmountback", balance);//发包者剩余的钱
            moneyRecode.getJSONObject(sendUserId).put("resultMoney", bankWinMoney);
            JSONArray array = new JSONArray();
            for (String userId : moneyRecode.keySet()) {
                JSONObject resultItem = moneyRecode.getJSONObject(userId);
                long total = 0;
                total += resultItem.getLongValue("sendAmount") + resultItem.getLongValue("sendAmountback") + resultItem.getLongValue("robMoney") + resultItem.getLongValue("resultMoney");
                long drawWater = getWinAmount(total, playerMap.get(userId));//手续费
                if (moneyRecode.keySet().size() == 1 && userId.equals(sendUserId)) {
                    //只有发包者自己的话不算手续费
                    drawWater = 0;
                }
                resultItem.put("drawWater", drawWater);

                long totalFreeze = 0;
                long finalMoney = total - drawWater;

                if (userId.equals(sendUserId)) {
                    totalFreeze = sendDeposit;
                } else {
                    totalFreeze = robDeposit;
                }
                resultItem.put("total", finalMoney);
                playerMap.get(userId).onSettlement(rpId, finalMoney + totalFreeze, -totalFreeze);
                array.add(Wallet.addMoneySql(playerMap.get(userId), finalMoney, 0,roomId));
                array.add(SettlementResult.makeResult(this, resultItem, userId, World.LONGHU));//插入流水账单
            }
            array.add(RpMassage.insertRpMessage(rpId, roomId, World.LONGHU, 2));

            MysqlService.getInstance().executeMultipleAsyn(array);
            Out.debug("龙虎红包详情：", this.toString());
            Out.debug("龙虎红包记录：", rpResult);

            GamePushRedPackageByProto.PushRedPackage.Builder push = GamePushRedPackageByProto.PushRedPackage.newBuilder();
            push.setGameId(4);
            push.setRoomId(roomId);
            push.setRpId(rpId);
            World.getInstance().games.get(World.LONGHU).rooms.get(roomId).broadcast(PushAndSaved.pushProto("", "push.RedPackage", push), "proxy");
            for (Player current : playerMap.values()) {
                MsgService.pushBySID(PushAndSaved.pushProto(current.userId, "push.RedPackageResult", push), current.SID);
            }

            niuNiuJoinRedis();
            longHuRoom.rpPackage.remove(rpId);//内存中移除红包
        } catch (Exception e) {
            Out.error("牛牛结算报错");
            Out.error(this.toString());
            e.printStackTrace();
        }
    }

    //发包者赢
    public void sendWin(String userId, long transportAmount, long winAmount) {
        Out.debug("-----------发包者赢---------------");
        Wallet.DeductMoney(playerMap.get(userId), transportAmount, -robDeposit);//抢包者扣钱--并且解冻金额
        TradeRecord.generateRecord(userId, rpId, -transportAmount, 0, 2, World.LONGHU, roomId);// 1.发包扣钱  2.结算扣钱  3.加钱（不参与手续费） 4.加钱（参与手续费） 5.撤回


        Wallet.addMoney(playerMap.get(sendUserId), winAmount, 0);//发包者加钱
        TradeRecord.generateRecord(sendUserId, rpId, winAmount, transportAmount - winAmount, 4, World.LONGHU, roomId);// 1.发包扣钱  2.结算扣钱  3.加钱（不参与手续费） 4.加钱（参与手续费） 5.撤回
    }

    //抢包者赢
    public void robWin(String userId, long transportAmount, long winAmount) {
        Out.debug("-----------抢包者赢---------------");
        Wallet.addMoney(playerMap.get(userId), winAmount, robDeposit);//抢包者加钱--并且解冻金额
        TradeRecord.generateRecord(userId, rpId, winAmount, transportAmount - winAmount, 4, World.LONGHU, roomId);// 1.发包扣钱  2.结算扣钱  3.加钱（不参与手续费） 4.加钱（参与手续费） 5.撤回


        Wallet.DeductMoney(playerMap.get(sendUserId), transportAmount, 0);//发包者扣钱----这里不能解冻（如果这里就解冻的话会循环解冻多次）
        TradeRecord.generateRecord(sendUserId, rpId, -transportAmount, 0, 2, World.LONGHU, roomId);// 1.发包扣钱  2.结算扣钱  3.加钱（不参与手续费） 4.加钱（参与手续费） 5.撤回
    }


    //Redis 红包详情入库
    public void niuNiuJoinRedis() {
        //将红包记录修改到MySql库里
        Map<String, String> rpInfo = new HashMap<>();
        rpInfo.put("sendUserId", sendUserId);//发红包者
        rpInfo.put("gameId", String.valueOf(World.LONGHU));//游戏Id
        rpInfo.put("roomId", String.valueOf(roomId));//房间Id
        rpInfo.put("RpId", rpId);//红包ID
        rpInfo.put("count", String.valueOf(count));//红包余数
        rpInfo.put("sumCount", String.valueOf(sumCount));//红包总个数
        rpInfo.put("amount", String.valueOf(amount));//红包金额
        rpInfo.put("balance", String.valueOf(balance));//红包余额
        rpInfo.put("moneyPieces", JSON.toJSONString(moneyPieces));//金额分配
        rpInfo.put("rpResult", String.valueOf(rpResult));//红包结果
        rpInfo.put("time", String.valueOf(time));//红包时间
        rpInfo.put("status", String.valueOf(status));//红包状态  0:发出 1:完成  2.撤回
        rpInfo.put("robDeposit", String.valueOf(robDeposit));//押金
        rpInfo.put("victoryNumber", String.valueOf(victoryNumber));//发包者胜率
        rpInfo.put("long", String.valueOf(longy));//龙的点数
        rpInfo.put("hu", String.valueOf(hu));//虎的点数
        rpInfo.put("detain", String.valueOf(detain));//发包者押的类型
        rpInfo.put("wol", String.valueOf(wol));//龙虎输赢结果
        rpInfo.put("longyNumber", String.valueOf(longyNumber));
        R_REDPACKAGE_INFO.hmset(rpId, rpInfo);

    }


    //得到输的金额
    public long getTransportAmount(double magnification) {
        //赢的金额 = 金额 * 倍率
        return (long) (amount * magnification);
    }

}
